﻿#region

using System;
using System.IO;
using System.Reflection;
using EsbMonitorExtension.MonitorTasks.Base;
using EsbMonitorMessages.Domain;
using EsbMonitorMessages.Events;
using log4net;
using NServiceBus.Unicast;
using NServiceBus.Utils;

#endregion

namespace EsbMonitorExtension.MonitorTasks
{
    public class MessageAssembliesLoadedTask : BaseMonitorTask
    {
        private static readonly ILog Logger = LogManager.GetLogger(typeof (MessageAssembliesLoadedTask));

        public MessageAssembliesLoadedTask(IUnicastBus bus) : base(bus)
        {
        }

        public override void RunTask()
        {

            Logger.Info("Running MessageAssembliesLoadedTask");

            UnicastBus unicastBus = Bus as UnicastBus;

            if (unicastBus == null)
            {
                throw new ApplicationException("Could not obtain UnicastBus");
            }

            foreach (String assemblyName in unicastBus.MessageOwners.Keys)
            {
                Logger.Info("Found assembly: " + assemblyName);
                if (IsNotStandardAssembly(assemblyName))
                {
                    Assembly assembly = Assembly.Load(assemblyName);
                    RaiseMessageAssemblyLoadedEvent(assembly);
                }
            }

            Logger.Info("Finished MessageAssembliesLoadedTask");
        }

        private bool IsNotStandardAssembly(string messageOwner)
        {
            return !messageOwner.StartsWith("NServiceBus") && !messageOwner.StartsWith("EsbMonitorMessages");
        }

        private void RaiseMessageAssemblyLoadedEvent(Assembly assembly)
        {
            string assemblyFullName = assembly.FullName;
            string location = assembly.Location;
            string fileName = assembly.ManifestModule.ScopeName;

            byte[] binaryData = File.ReadAllBytes(location);

            Bus.Send<IMessageAssemblyLoaded>(m =>
                                                 {
                                                     m.ServiceInfo = Bus.ServiceInfo();
                                                     m.MessageAssemblyInfo = new MessageAssemblyInfo(assemblyFullName);
                                                     m.FileName = fileName;
                                                     m.EventTime = DateTime.Now;
                                                     m.BinaryData = binaryData;
                                                 }
                );
        }
    }
}